﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace Crazy_Crafter
{
    public partial class Form1 : Form
    {
        MemoryManager GameMemory;
        StatusDisplay Status = new StatusDisplay();
        int XpHr = 0; int LastXp;
        int LastXpHr; int LastHr;
        int SpHr = 0; int LastSp;
        int LastJob;
        bool LastRun = false;
        bool FirstRun = true;
        int br = 0, su = 0;
        bool writing = false; bool reading = false;
        byte[] Stability = { 0, 0, 0, 0, 0, 0 };

        List<string> ChatLines = new List<string>();

        public Form1()
        {
            InitializeComponent();

            Process[] P = Process.GetProcessesByName("ffxivgame");
            if (P.Count() == 0)
            {
                MessageBox.Show("Unable to detect Final Fantasy XIV.", "Closing Application");
                Application.Exit();
                Environment.Exit(0);
            }
            else if (P.Count() > 1)
            {
                ProcessBox PB = new ProcessBox(P);
                if (PB.ShowDialog(this) == DialogResult.OK)
                {
                    GameMemory = new MemoryManager(P[PB.Index]);
                }
                else
                {
                    MessageBox.Show("Unable to detect Final Fantasy XIV.", "Closing Application");
                    Application.Exit();
                    Environment.Exit(0);
                }
            }
            else
            {
                GameMemory = new MemoryManager(P[0]);
            }

            Crazy_Crafter.Properties.Settings.Default.Reload();
            this.synthesisType.SelectedIndex = 0;

            display.Enabled = true;
            //            windowdetect.Enabled = true;
            display_Tick(null, new EventArgs());
        }

        int LastChat = 0;
        private void display_Tick(object sender, EventArgs e)
        {
            display.Enabled = false;
            if (!GameMemory.CheckGame())
            {
                display.Enabled = false;
                MessageBox.Show("Final Fantasy XIV has been closed." + (char)13 + (char)13 + "Application Exiting.");
                Application.Exit();
                Environment.Exit(0);
            }

            if (FirstRun == false)
            {
                if (GameMemory.GetLevelExperience() < progressBar2.Value)
                {
                    XpHr += (GameMemory.GetLevelExperience() + GameMemory.GetLevelMaxExperience(-1)) - progressBar2.Value;
                }
                else
                {
                    XpHr += GameMemory.GetLevelExperience() - progressBar2.Value;
                }

                if (LastJob == GameMemory.GetJobID())
                {
                    if (GameMemory.GetJobExperience() < progressBar1.Value)
                    {
                        SpHr += (GameMemory.GetJobExperience() + GameMemory.GetJobMaxExperience(-1)) - progressBar1.Value;
                    }
                    else
                    {
                        SpHr += GameMemory.GetJobExperience() - progressBar1.Value;
                    }
                }
                else
                {
                    LastJob = GameMemory.GetJobID();
                    SpHr = 0;
                }
            }
            else
            {
                FirstRun = false;
            }

            try
            {
                string cName = GameMemory.GetCharacterName();
                if (cName.Length == 0)
                {

                }
                label1.Text = string.Format("Name: {0}", cName);
                label2.Text = string.Format("Job: {0} {1} - Level: {2}", GameMemory.GetJobLevel(), GameMemory.GetJobName(), GameMemory.GetLevel());
                progressBar1.Maximum = GameMemory.GetJobMaxExperience();
                progressBar1.Value = GameMemory.GetJobExperience();
                label3.Text = string.Format("Rank: {0} / {1}", progressBar1.Value.ToString(), progressBar1.Maximum.ToString());
                progressBar2.Maximum = GameMemory.GetLevelMaxExperience();
                progressBar2.Value = GameMemory.GetLevelExperience();
                label4.Text = string.Format("Level: {0} / {1}", progressBar2.Value.ToString(), progressBar2.Maximum.ToString());
            }
            catch (Exception ex)
            {
            }

            if (SpHr > 0 || SpHr > 0)
            {
                LastXpHr++;
                float Timer = LastXpHr / 2;
                Status.lblxp.Text = progressBar1.Value.ToString() + " / " + progressBar1.Maximum.ToString() + " (" + (SpHr / Timer * 3600) + ") -- " + progressBar2.Value.ToString() + " / " + progressBar2.Maximum.ToString() + " (" + (XpHr / Timer * 3600) + ")";

                if (SpHr != LastSp || XpHr != LastXp)
                {
                    LastHr = LastXpHr;
                }
                else
                {
                    if ((LastXpHr - LastHr) > 1200)
                    {
                        LastXpHr = 0;
                        LastHr = 0;
                        XpHr = 0;
                        SpHr = 0;
                        LastXp = 0;
                        LastSp = 0;
                    }
                }
            }
            else
            {
                Status.lblxp.Text = progressBar1.Value.ToString() + " / " + progressBar1.Maximum.ToString() + " (0) -- " + progressBar2.Value.ToString() + " / " + progressBar2.Maximum.ToString() + " (0)";
            }


            if (!writing)
            {
                reading = true;
                FileStream f = new FileStream(@"sb.sdk", FileMode.OpenOrCreate, FileAccess.Read);
                if (f.Length > 0)
                {
                    byte[] b = new byte[8];
                    f.Read(b, 0, 8);
                    su = BitConverter.ToInt32(b, 0);
                    br = BitConverter.ToInt32(b, 4);
                }
                f.Close();
                lblSuccess.Text = su + " : Successful";
                lblBreak.Text = br + " : Breaks";
                reading = false;
            }

            //            Crazy_Crafter.Properties.Settings.Default.Save();

            /*
            debugBox2.Text = GetVolumeSerial("C");
            if (args == null || args.Length == 0)
            {
                throw new ApplicationException("Specify the URI of the resource to retrieve.");
            }
            WebClient client = new WebClient();

            // Add a user agent header in case the 
            // requested URI contains a query.

            client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");

            Stream data = client.OpenRead(args[0]);
            StreamReader reader = new StreamReader(data);
            string s = reader.ReadToEnd();
            Console.WriteLine(s);
            data.Close();
            reader.Close();
*/

            if (LastChat == 0)
            {
                LastChat = GameMemory.GetChatLineNumber();
                LastChat = (LastChat - (LastChat % 60) - 25);
                if (LastChat < 0)
                {
                    LastChat = 0;
                }
            }

            for (int c = GameMemory.GetChatLineNumber(); LastChat < c; LastChat++)
            {
                string chatLine = GameMemory.GetChatLine(LastChat % 60);
                string DebugLine = chatLine;
                if (chatLine.Length > 6)
                {
                    try
                    {
                        string chatCode = chatLine.Substring(0, 4);
                        chatLine = chatLine.Substring(5);
                        if (chatLine.Substring(0, 1).Equals(":"))
                        {
                            chatLine = chatLine.Substring(1);
                        }
                        string Time = DateTime.Now.ToShortTimeString();
                        int s1 = 0, s2 = 0;
                        if (this.chatLog.SelectionStart != this.chatLog.TextLength)
                        {
                            s1 = this.chatLog.SelectionStart;
                            s2 = this.chatLog.SelectionLength;
                            this.chatLog.SelectionStart = this.chatLog.TextLength;
                        }

                        if (chatCode.Equals("0020"))
                        {
                            Stability[0] = StabilityCheck(chatLine, "Water", Stability[0]);
                            Stability[1] = StabilityCheck(chatLine, "Earth", Stability[1]);
                            Stability[2] = StabilityCheck(chatLine, "Ice", Stability[2]);
                            Stability[3] = StabilityCheck(chatLine, "Fire", Stability[3]);
                            Stability[4] = StabilityCheck(chatLine, "Lightning", Stability[4]);
                            Stability[5] = StabilityCheck(chatLine, "Wind", Stability[5]);

                            if (Regex.Match(chatLine, "You are unable to carry that many (.*).", RegexOptions.IgnoreCase).Length > 0)
                            {
                                if (MessageBox.Show(this, "You cannot hold any more of the products.\n\nDo you wish to continue?", "Product Full", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No)
                                {
                                    startstop_Click(null, null);
                                }
                            }
                            else if (Regex.Match(chatLine, "You do not have the crystal required to start the synthesis.", RegexOptions.IgnoreCase).Length > 0)
                            {
                                startstop_Click(null, null);
                                MessageBox.Show(this, "You have run out of the proper crystals.\n\nCrafting Terminated", "Crystals Empty", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            }
                            else if (Regex.Match(chatLine, "You obtain (.{1,3}) (.*)\\.", RegexOptions.IgnoreCase).Length > 0)
                            {
                                string data = Regex.Replace(chatLine, "You obtain (.{1,3}) (.*)\\.", "$1|$2");
                            }
                            else if (Regex.Match(chatLine, "You use (.{1,3}) (.*)\\.", RegexOptions.IgnoreCase).Length > 0)
                            {
                                string data = Regex.Replace(chatLine, "You use (.{1,3}) (.*)\\.", "$1|$2");
                            }
                        }

                        this.chatLog.SelectionColor = getChatForeground(chatCode);
                        this.chatLog.SelectionBackColor = getChatBackground(chatCode);
                        this.chatLog.SelectedText = string.Format("[{0}] {1}: {2}\n", chatCode, DateTime.Now.ToShortTimeString(), chatLine);

                        if (s1 > 0)
                        {
                            this.chatLog.SelectionStart = s1;
                            this.chatLog.SelectionLength = s2;
                        }
                        else
                        {
                            this.chatLog.SelectionStart = this.chatLog.TextLength;
                            this.chatLog.ScrollToCaret();
                        }
                    }
                    catch (ArgumentException ae)
                    {
                        this.chatLog.SelectionColor = Color.Red;
                        this.chatLog.SelectionBackColor = Color.Black;
                        this.chatLog.SelectedText = string.Format("[INVALID] ~~{0}~~\n", DebugLine);
                    }
                }
                else break;
            }
            elementBoxWater.Image = imageList.Images[string.Format("{0}1.png", Stability[0])];
            elementBoxEarth.Image = imageList.Images[string.Format("{0}2.png", Stability[1])];
            elementBoxIce.Image = imageList.Images[string.Format("{0}3.png", Stability[2])];
            elementBoxFire.Image = imageList.Images[string.Format("{0}4.png", Stability[3])];
            elementBoxLightning.Image = imageList.Images[string.Format("{0}5.png", Stability[4])];
            elementBoxWind.Image = imageList.Images[string.Format("{0}6.png", Stability[5])];

            display.Enabled = true;
        }

        private byte StabilityCheck(string chatLine, string Element, byte baseStability)
        {
            if (baseStability == 2) return 2;
            if (Regex.Replace(chatLine, "The harnessed (.*) element becomes unstable!", "$1", RegexOptions.None).Equals(Element))
            {
                return 1;
            }
            else
            {
                if (Regex.Replace(chatLine, "The harnessed (.*) element stabilizes.", "$1", RegexOptions.None).Equals(Element))
                {
                    return 0;
                }
                else
                {
                    if (Regex.Match(chatLine, "You use (.*) Synthesis. The element grows chaotic!", RegexOptions.IgnoreCase).Length > 0)
                    {
                        return 2;
                    }
                }
            }
            return baseStability;
        }

        protected Bitmap CopyBitmap(Bitmap source, Rectangle part)
        {
            Bitmap bmp = new Bitmap(part.Width, part.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.DrawImage(source, 0, 0, part, GraphicsUnit.Pixel);
            g.Dispose();
            return bmp;
        }

        private Color getChatForeground(string chatCode)
        {
            int code = Int32.Parse(chatCode, System.Globalization.NumberStyles.HexNumber);
            FileStream f = new FileStream(@"chat.sdk", FileMode.Open, FileAccess.Read);
            f.Seek(code * 8, SeekOrigin.Begin);
            byte[] b = new byte[4];
            f.Read(b, 0, 4);
            f.Close();
            return Color.FromArgb(BitConverter.ToInt32(b, 0) & 0xffffff);
        }

        private Color getChatBackground(string chatCode)
        {
            int code = Int32.Parse(chatCode, System.Globalization.NumberStyles.HexNumber);
            FileStream f = new FileStream(@"chat.sdk", FileMode.Open, FileAccess.Read);
            f.Seek(code * 8 + 4, SeekOrigin.Begin);
            byte[] b = new byte[4];
            f.Read(b, 0, 4);
            f.Close();
            return Color.FromArgb(BitConverter.ToInt32(b, 0) & 0xffffff);
        }

        private void label3_Click(object sender, EventArgs e)
        {

        }
        private bool KeyDown = false;
        private bool Finished = true;
        private bool First = true;
        private int loopTest = 0;

        private void windowdetect_Tick(object sender, EventArgs e)
        {
            windowdetect.Enabled = false;
            string s = "";

            MemoryManager.XIVWindow window = new MemoryManager.XIVWindow();
            window = GameMemory.getWindow("Window_Ask/JournalListWidget");
            if (window.start > 0)
            {
                GameMemory.SendEscape();
                GameMemory.Sleeper(200);
                KeyDown = false;
            }
            window = GameMemory.getWindow("Window_CraftProgressWidget");
            s = s + "Window: " + window.tag + " - " + window.start + (char)13;
            if (window.start > 0)
            { // Crafting Progress Window Visible
                int WindowStatus = GameMemory.getWindowData("Window_CraftProgressWidget", 0x53, 1);
                int Complete = GameMemory.getWindowData("Window_CraftProgressWidget", 73, 1);
                int Durability = GameMemory.getWindowData("Window_CraftProgressWidget", 75, 2);
                int Quality = GameMemory.getWindowData("Window_CraftProgressWidget", 79, 2);
                int Selection = GameMemory.getWindowData("Window_CraftProgressWidget", 0x7C, 2);
                /* * Selection Values
                 * --
                 * 22586 - Standard Synth
                 * 22587 - Rapid Synth
                 * 22588 - Bold Synth
                 * 22506 - Wait
                 * 29502 - Hasty Hands
                 * */
                int[] synthesisList = { 22586, 22587, 22588 };

                switch (Selection)
                {
                    case 22586:
                        s = s + (char)13 + "Selected: Standard";
                        break;
                    case 22587:
                        s = s + (char)13 + "Selected: Rapid";
                        break;
                    case 22588:
                        s = s + (char)13 + "Selected: Bold";
                        break;
                    case 22506:
                        s = s + (char)13 + "Selected: Wait";
                        break;
                    case 29502:
                        s = s + (char)13 + "Selected: Hasty Hands";
                        break;
                }

                /*                byte[] dbg = new byte[0x180]; byte[] dbg2 = new byte[0x180];
                                dbg = GameMemory.getWindowBytes("Window_CraftProgressWidget");

                                if (!dbg.Equals(dbg2))
                                {
                                    dbg2 = dbg;
                                //    debugBox2.Text = debugBox2.Text + (char)13 + BitConverter.ToString(dbg);
                                }
                */
                if (WindowStatus == 5)
                {
                    if (hastyhands.Checked && First == true)
                    {
                        First = false;
                        while (Selection != 29502)
                        {
                            GameMemory.Sleeper(100);
                            GameMemory.SendUp();
                            Selection = GameMemory.getWindowData("Window_CraftProgressWidget", 0x7C, 2);
                            if (Selection == synthesisList[synthesisType.SelectedIndex]) break;
                        }
                    }
                    else if ((!hastyhands.Checked) || (hastyhands.Checked && First == false))
                    {
                        while (Selection != synthesisList[synthesisType.SelectedIndex])
                        {
                            GameMemory.Sleeper(100);
                            GameMemory.SendDown();
                            Selection = GameMemory.getWindowData("Window_CraftProgressWidget", 0x7C, 2);
                        }
                    }
                    GameMemory.Sleeper(100);
                    GameMemory.SendEnter();
                }

                if (WindowStatus == 3 || WindowStatus == 7)
                {
                    First = true;
                    GameMemory.Sleeper(100);
                    GameMemory.SendEnter();
                }

                KeyDown = false;
                if (Finished == false)
                {
                    if (Durability == 0)
                    {
                        br++;
                        while (reading) GameMemory.Sleeper(50);
                        writing = true;
                        FileStream f = new FileStream(@"sb.sdk", FileMode.Open);
                        byte[] b = BitConverter.GetBytes(br);
                        f.Seek(4, SeekOrigin.Begin);
                        f.Write(b, 0, 4);
                        f.Close();
                        writing = false;
                        Finished = true;
                        First = true;
                    }
                    else if (Complete == 100)
                    {
                        su++;
                        while (reading) GameMemory.Sleeper(50);
                        writing = true;
                        FileStream f = new FileStream(@"sb.sdk", FileMode.Open);
                        byte[] b = BitConverter.GetBytes(su);
                        f.Write(b, 0, 4);
                        f.Close();
                        writing = false;
                        Finished = true;
                        First = true;
                    }
                }

                lblComplete.Text = "Complete: " + Complete.ToString() + "%";// +Selection.ToString();
                lblDurability.Text = "Durability: " + Durability.ToString();
                lblQuality.Text = "Quality: " + Quality.ToString();
                pgbCompletion.Value = Complete;
            }

            MemoryManager.XIVWindow recipe = GameMemory.getWindow("Window_CraftRecipeWidget");
            window = GameMemory.getWindow("Window_CraftStartWidget");
            s = s + "Window: " + window.tag + " - " + window.start + (char)13;
            if (window.start > 0)
            { // Crafting Starting Window Visible

                if (recipe.start > 0)
                {
                    loopTest++;
                    if (loopTest > 5)
                    {
                        loopTest = 0;
                        GameMemory.SendEnter();
                    }
                }
                s = s + "Craft Window Open" + (char)13;
                int WindowStatus = GameMemory.getWindowData("Window_CraftEditWidget", 0x51, 1);
                int WindowStatus2 = GameMemory.getWindowData("Window_CraftEditWidget", 0x59, 1);
                int RecipePosition = GameMemory.getWindowData("Window_CraftEditWidget", 0x59, 2);
                int RecipeSelect = GameMemory.getWindowData("Window_CraftEditWidget", 0x5B, 2);
                s = s + "Window Status: " + WindowStatus + (char)13;
                if (WindowStatus == 4 && WindowStatus2 == 0) // Manual Recipe (Last Item)
                {
                    s = s + "Inventory Open" + (char)13;
                }
                else if (WindowStatus == 4 && WindowStatus2 == 2) // Craft Recipe
                {
                    s = s + "Craft Recipe Window Open" + (char)13;
                    s = s + "Recipe Hover: " + (RecipePosition + 1) + (char)13;
                    if (WindowStatus2 == 5) // Recipe Selected
                    {
                        s = s + "Recipe Selected: " + (RecipeSelect + 1) + (char)13;
                    }
                }
                else if (WindowStatus == 0 && WindowStatus2 == 1) // Confirm Recipe
                {
                    s = s + "Confirm Recipe" + (char)13;
                }

                if (LastRun == true && KeyDown == false)
                {
                    startstop.BackColor = ButtonBase.DefaultBackColor;
                    startstop.Tag = "";
                }
                else if (KeyDown == false)
                {
                    KeyDown = true;
                    for (int x = 0; x < 6; x++) Stability[x] = 0;
                    if (craftmodecraft.Checked)
                    {
                        GameMemory.Sleeper(300);
                        GameMemory.SendDown();
                        GameMemory.Sleeper(100);
                        GameMemory.SendEnter();
                        GameMemory.Sleeper(300);
                        GameMemory.SendEnter();
                        if (secondarytool.Checked)
                        {
                            GameMemory.Sleeper(100);
                            GameMemory.SendDown();
                        }
                        GameMemory.Sleeper(400);
                        GameMemory.SendEnter();
                        GameMemory.Sleeper(400);
                        GameMemory.SendEnter();
                    }
                    else if (craftmodeitem.Checked)
                    {
                        GameMemory.Sleeper(300);
                        int DownPosition = GameMemory.getWindowData("Window_CraftStartWidget", 78, 1);
                        int counter = 0;
                        while (DownPosition != 1 && counter >= 0)
                        {
                            if (counter < 10)
                            {
                                GameMemory.SendDown();
                            }
                            else if (counter < 20)
                            {
                                GameMemory.SendUp();
                            }
                            else
                            {
                                counter = -10;
                            }
                            GameMemory.Sleeper(50);
                            DownPosition = GameMemory.getWindowData("Window_CraftStartWidget", 78, 1);
                            counter++;
                        }
                        GameMemory.SendEnter();
                        GameMemory.Sleeper(300);
                        GameMemory.SendUp();
                        GameMemory.Sleeper(100);
                        GameMemory.SendEnter();
                        GameMemory.Sleeper(100);
                        GameMemory.SendEscape();
                        GameMemory.Sleeper(100);
                        GameMemory.SendDown();
                        GameMemory.Sleeper(100);
                        GameMemory.SendDown();
                        if (secondarytool.Checked)
                        {
                            GameMemory.Sleeper(100);
                            GameMemory.SendDown();
                        }
                        GameMemory.Sleeper(100);
                        GameMemory.SendEnter();
                        GameMemory.Sleeper(400);
                        GameMemory.SendEnter();
                        GameMemory.Sleeper(400);
                        GameMemory.SendEnter();
                    }
                }
                Finished = false;
            }

            if (startstop.Tag != "")
            {
                windowdetect.Enabled = true;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (button1.Tag == "1")
            {
                Status.Hide();
                button1.Tag = "";
            }
            else
            {
                Status.Show();
                button1.Tag = "1";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (button2.Tag == "1")
            {
                GameMemory.ChangeVisible(false);
                button2.Tag = "";
            }
            else
            {
                GameMemory.ChangeVisible(true);
                button2.Tag = "1";
            }
        }

        private void startstop_Click(object sender, EventArgs e)
        {
            if (startstop.Tag == "" || startstop.Tag == null)
            {
                startstop.Tag = "1";
                windowdetect.Enabled = true;
                LastRun = false;
                startstop.Text = "Stop";
                startstop.BackColor = Color.Green;
            }
            else if (startstop.Tag == "1" && LastRun == true)
            {
                LastRun = false;
                startstop.Text = "Stop";
                startstop.BackColor = Color.Green;
            }
            else
            {
                if (KeyDown == false && Finished == true)
                {
                    windowdetect.Enabled = false;
                    startstop.Tag = null;
                    startstop.BackColor = ButtonBase.DefaultBackColor;
                }
                else
                {
                    startstop.Tag = "1";
                }
                LastRun = true;
                startstop.Text = "Start";
            }
        }

        [DllImport("kernel32.dll")]
        private static extern long GetVolumeInformation(string PathName, StringBuilder VolumeNameBuffer, UInt32 VolumeNameSize, ref UInt32 VolumeSerialNumber, ref UInt32 MaximumComponentLength, ref UInt32 FileSystemFlags, StringBuilder FileSystemNameBuffer, UInt32 FileSystemNameSize);
        public string GetVolumeSerial(string strDriveLetter)
        {
            uint serNum = 0;
            uint maxCompLen = 0;
            StringBuilder VolLabel = new StringBuilder(256); // Label
            UInt32 VolFlags = new UInt32();
            StringBuilder FSName = new StringBuilder(256); // File System Name
            strDriveLetter += ":\\"; // fix up the passed-in drive letter for the API call
            long Ret = GetVolumeInformation(strDriveLetter, VolLabel, (UInt32)VolLabel.Capacity, ref serNum, ref maxCompLen, ref VolFlags, FSName, (UInt32)FSName.Capacity);

            return serNum.ToString("x");
            //            return Convert.ToString(serNum);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (chatLog.Visible == true)
            {
                chatLog.Visible = false;
                this.Width = this.MinimumSize.Width;
                button3.Text = "Show Chat";
            }
            else
            {
                if (chatColor.Visible == true)
                    chatColor.Visible = false;
                chatLog.Visible = true;
                this.Width = this.MaximumSize.Width;
                button3.Text = "Hide Chat";
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (chatColor.Visible == true)
            {
                chatColor.Visible = false;
                this.Width = this.MinimumSize.Width;
            }
            else
            {
                if (chatLog.Visible == true)
                {
                    chatLog.Visible = false;
                    button3.Text = "Show Chat";
                }
                chatColor.Visible = true;
                this.Width = this.MaximumSize.Width;
            }
        }

        private void craftmodecraft_CheckedChanged(object sender, EventArgs e)
        {
            Crazy_Crafter.Properties.Settings.Default.Save();
        }

        private void secondarytool_CheckedChanged(object sender, EventArgs e)
        {
            Crazy_Crafter.Properties.Settings.Default.Save();
        }

        private void hastyhands_CheckedChanged(object sender, EventArgs e)
        {
            Crazy_Crafter.Properties.Settings.Default.Save();
        }

        private void craftmodeitem_CheckedChanged(object sender, EventArgs e)
        {
            Crazy_Crafter.Properties.Settings.Default.Save();
        }

        public byte[] Dexor(byte[] srcBuffer)
        {
            byte[] dstBuffer = new byte[srcBuffer.Length];

            for (int x = 0; x < srcBuffer.Length; x++)
            {
                dstBuffer[x] = (byte)((int)srcBuffer[x] ^ 0x73);
            }
            return dstBuffer;
        }
        /// <summary>
        /// Will decode the passed byte array
        /// </summary>
        /// <param name="srcBuffer">The array to decode</param>
        /// <param name="srcLen">The length of the array</param>
        public static byte[] Decode(byte[] srcBuffer)
        {
            byte[] dstBuffer;

            // encoded files always end with 0xF1 so lets make sure that's there
            if (srcBuffer[srcBuffer.Length - 1] != 0xF1)
            {
                dstBuffer = new byte[srcBuffer.Length];
                srcBuffer.CopyTo(dstBuffer, 0);
                return dstBuffer;

            } // @ if (srcBuffer[srcBuffer.Length - 1] != 0xF1)

            // create our destination buffer
            dstBuffer = new byte[srcBuffer.Length - 1];

            unsafe
            {
                int encodedLen = srcBuffer.Length - 1;

                if (encodedLen > dstBuffer.Length)
                {
                    throw new InvalidOperationException("Destination buffer of insufficient size");
                }

                // Initialize dstBuffer to be the same as srcBuffer
                Array.Copy(srcBuffer, dstBuffer, encodedLen);

                fixed (byte* dst = dstBuffer)
                fixed (byte* src = srcBuffer)
                {
                    short xA;
                    short xB;

                    ScrambleBuffer(dst, encodedLen);

                    xA = (short)(7 * encodedLen);

                    // This is kind of a hack!
                    // The following relies on the decrypted file beginning with (UTF8::BOF)<?xml
                    // Therefore, this only works for XML encrypted using this method
                    xB = (short)((int)*(short*)(dst + 6) ^ 0x6C6D);

                    short* ptr = (short*)dst;
                    byte* dstEnd = &dst[encodedLen];

                    do
                    {
                        *ptr ^= xA;
                        ptr += 2;

                    } while (ptr < dstEnd);

                    ptr = (short*)(dst + 2);

                    do
                    {
                        *ptr ^= xB;
                        ptr += 2;

                    } while (ptr < dstEnd);

                    // This may need to be *((byte*)xB + 1) or something
                    // if the last byte ever ends up breaking
                    if ((encodedLen & 1) != 0)
                        *(dstEnd - 1) = (byte)(*(dstEnd - 1) ^ (byte)(xB & 0xFF));

                } // @ fixed (byte* src = srcBuffer)
            } // @ unsafe

            return dstBuffer;

        } // @ public static byte[] Decode(byte[] srcBuffer)

        /// <summary>
        /// reverses the byte array
        /// </summary>
        /// <param name="dst">The buffer we're copying the data too</param>
        /// <param name="len">Length of the data being copied</param>
        private unsafe static void ScrambleBuffer(byte* dst, int len)
        {
            byte tmp;
            byte* ptr = dst;            // pointer to the beginning of the array
            byte* end = &dst[len - 1];  // pointer to the end of the array

            // if we have data to read
            if (ptr < end)
            {
                do
                {
                    tmp = *end;    // save the end byte
                    *end = *ptr;    // set the end byte as the current byte
                    *ptr = tmp;     // set the current byte as the original end byte
                    ptr += 2;       // move the pointer 2 bytes ahead
                    end -= 2;       // move the pointer 2 bytes behind

                } while (ptr < end);

            } // @ if (ptr < end)
        } // @ private unsafe static void ScrambleBuffer(byte* dst, int len)}

        private void button5_Click(object sender, EventArgs e)
        {
            FileStream f = File.Open("D:/SquareEnix/FINAL FANTASY XIV/data/0B/45/08/EC.DAT", FileMode.Open, FileAccess.Read);
            byte[] b = new byte[f.Length];
            f.Read(b, 0, (int)f.Length);
            f.Close();
            b = Dexor(b);
            string s = ASCIIEncoding.ASCII.GetString(b);
            MessageBox.Show(s);
        }
    }
}
